import dayjs from 'dayjs'
import OSS from 'ali-oss'
import api from '@/api/index'
import { useUserStore } from '@/store'

/**
 * @desc  格式化时间
 * @param {(Object|string|number)} time
 * @param {string} format
 * @returns {string | null}
 */
export function formatDateTime(
  time = undefined,
  format = 'YYYY-MM-DD HH:mm:ss'
) {
  if (time) {
    return dayjs(time).format(format)
  } else {
    return ''
  }
}

export function formatDate(date = undefined, format = 'YYYY-MM-DD') {
  return formatDateTime(date, format)
}

/**
 * @desc  函数节流
 * @param {Function} fn
 * @param {Number} wait
 * @returns {Function}
 */
export function throttle(fn, wait) {
  var context, args
  var previous = 0

  return function () {
    var now = +new Date()
    context = this
    args = arguments
    if (now - previous > wait) {
      fn.apply(context, args)
      previous = now
    }
  }
}

/**
 * @desc  函数防抖
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(method, wait, immediate) {
  let timeout
  return function (...args) {
    let context = this
    if (timeout) {
      clearTimeout(timeout)
    }
    // 立即执行需要两个条件，一是immediate为true，二是timeout未被赋值或被置为null
    if (immediate) {
      /**
       * 如果定时器不存在，则立即执行，并设置一个定时器，wait毫秒后将定时器置为null
       * 这样确保立即执行后wait毫秒内不会被再次触发
       */
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) {
        method.apply(context, args)
      }
    } else {
      // 如果immediate为false，则函数wait毫秒后执行
      timeout = setTimeout(() => {
        /**
         * args是一个类数组对象，所以使用fn.apply
         * 也可写作method.call(context, ...args)
         */
        method.apply(context, args)
      }, wait)
    }
  }
}

export function getOptions(dictValue = '', mode = '') {
  const dictList = JSON.parse(localStorage.getItem('dictList') || '[]')
  const dict = dictList.find((v) => v.dictValue === dictValue)

  if (mode === 'level') {
    return dict
      ? dict.children.map((v) => {
          return {
            label: v.dictLabel,
            value: v.dictValue,
            children: getOptions('disabilityLevel').map((d) => {
              return {
                label: `${v.dictLabel}(${d.label})`,
                value: `${v.dictValue}(${d.value})`,
              }
            }),
          }
        })
      : []
  } else {
    return dict
      ? dict.children.map((v) => {
          return {
            label: v.dictLabel,
            value: v.dictValue,
          }
        })
      : []
  }
}

export function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = (err) => reject(err)
  })
}

export async function getLoginUser() {
  const userStore = useUserStore()

  const { code, data } = await api.getLoginUser()

  if (code === 200) {
    const { code: code2, data: data2 } = await api.getLoginMenu()

    if (code2 === 200) {
      const authList = []

      data2.map((v) => {
        v.children.map((c) => {
          authList.push(c.name)

          if (c.children) {
            c.children.map((cc) => {
              authList.push(cc.name)

              if (cc.children) {
                cc.children.map((ccc) => {
                  authList.push(ccc.name)
                })
              }
            })
          }
        })
      })

      const userInfo = {
        ...data,
        authList,
      }
      userStore.setUserInfo(userInfo)
    }
  }
}

export function checkIsAuth(key = '') {
  const userRoles = useUserStore().role || []
  return userRoles.includes(key)
}

export function treeing(data = [], Pid = 0) {
  const tree = []

  data.map((v) => {
    if (v.Pid === Pid) {
      const item = {
        ...v,
        children: treeing(data, v.Id),
      }

      tree.push(item)
    }
  })

  return tree.length ? tree : null
}

export function objectToArray(target = [], keyName = 'id', isNumber = true) {
  if (typeof target != 'object') {
    return new Error('参数1 target（原对象）必须为object类型')
  }

  const result = []

  for (const key in target) {
    result.push({ [keyName]: isNumber ? Number(key) : key, ...target[key] })
  }

  return result
}

/**
 * 生成UUID
 */
export function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    let r = (Math.random() * 16) | 0,
      v = c == 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}
